home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-06 | 12.9 KB | 507 lines | [TEXT/MSET] |
- \ 29Aug94 DBH moved ListData init: to classinit:.
- \ It was being executed after new: !
- \ 28Oct94 dbh updated to 2.5 syntax
-
-
- (*
-
- An editlist is a scrollable/editable row and column matrix of text data. While
- resembling the ListManager note that we do *not* use any ListManager routines
- at all. Of course we follow our selection protocol so use is very simple and
- we can have multiple editlists in a window. The unique feature of an editlist
- is that the TextEdit field will appear *in* the current cell being edited.
-
- Note that classinit: contains all of the setup parameters (number of rows
- and columns and so forth). Default is 30 rows and 30 columns, but we
- don't display all at once. We can scroll through them. A subclass could
- easily have different values.
-
- Note also that we provide for a filterprocedure: method that could be
- over ridden to inspect data from a cell after it is entered, or any time
- we attempt to leave that cell. Here the filterprocedure: method simply
- returns true. Returning false would result in the user being returned to
- the offending cell until acceptable data was entered.
-
- *)
-
-
- :class editlist super{ nullselect }
-
- var #ofRows \ number of virtual rows of data
- var #ofColumns
- var CurrentRow
- var CurrentColumn
- int #ofDisplayRows
- int #ofDisplayColumns
- int Characters/Cell
- rect+ dataRect \ the scrollable data rectangle
- rect+ hitRect \ will enclose scrollbars as well
- rect+ DisplayRectangle
- rect+ VscrollRectangle \ the rectangle to scroll, not the control size
- rect+ HscrollRectangle \ the rectangle to scroll, not the control size
- int CellHeight
- int CellWidth
- te EditField
- vscrollBar VScrollControl
- hscrollBar HScrollControl
- 2arrayGen ListData
- int x
- int y
-
-
- :m classinit:
- 48 put: x
- 50 put: y
- 30 put: #ofRows
- 30 put: #ofColumns
- 5 put: #ofDisplayRows
- 4 put: #ofDisplayColumns
- 6 put: Characters/Cell
-
- get: #ofRows get: #ofColumns get: Characters/Cell init: ListData
-
- \ " Helvetica" putfontname: editfield \ 28Dec93 dbh this will work
- \ 15 putfontsize: editfield
-
- ;m
-
-
- :m DrawHorizontalLines: { \ y -- }
- get: #ofDisplayRows 1 ?DO
- getTopx: dataRect 1+ ( x)
- gettopy: dataRect I get: CellHeight * + ( y) dup -> y MoveTo
- getbotx: dataRect 1 - ( x) y ( y)
- LineTo LOOP ;m
-
- :m DrawVerticalLines: { \ x -- }
- get: #ofDisplayColumns 1 ?DO
- getTopx: dataRect I get: CellWidth * + ( x) dup -> x
- gettopy: dataRect ( y) MoveTo
- x ( x) getboty: dataRect 1- ( y) LineTo LOOP ;m
-
- :m DrawGrid:
- call PenNormal
- draw: DisplayRectangle
- 3 ( gray ) SYSPAT get: ** call PenPat
- DrawHorizontalLines: self
- DrawVerticalLines: self ;m
-
- :m init: \ must only call after new:
- lineheight: editField 1 + put: CellHeight
- widmax: editField get: Characters/Cell * 4 + put: CellWidth
-
- get: x ( x1) get: y ( y1)
- get: #ofDisplayColumns get: CellWidth * get: x + ( x2)
- get: #ofDisplayRows get: CellHeight * get: y + ( y2) put: dataRect
-
- get: dataRect ( x1 y1 x2 y2) 1+ swap 1+ swap put: DisplayRectangle
-
- gettopx: dataRect get: CellWidth - ( x1) gettopy: dataRect 1 + ( y1)
- getbotx: dataRect ( x2) getboty: dataRect ( y2)
- put: VscrollRectangle
-
- gettopx: dataRect 1 + ( x1) gettopy: dataRect get: CellHeight - 5 - ( y1)
- getbotx: dataRect ( x2) getboty: dataRect ( y2)
- put: HscrollRectangle
-
- get: dataRect put: hitRect 5 16 + ( dx) dup ( dy) stretch: hitRect
- ;m
-
- :m movepen: { row# col# -- } \ position QuickDraw pen for cell text display
- gettopx: dataRect col# get: CellWidth * + 2 + ( x)
- gettopy: dataRect row# get: CellHeight * + ascent: editField + 1+ ( y) \ 28Dec93 XXX
- MoveTo ;m
-
- :m DrawCellData: { row# col# -- }
- row# get: VScrollControl + ( row#indice )
- col# get: HScrollControl + ( col#indice )
- at: ListData mDrawString ;m
-
- :m DrawRowData: { row# -- }
- get: #ofDisplayColumns 0
- ?DO
- row# I movepen: self
- row# I DrawCellData: self
- LOOP ;m
-
- :m DrawData:
- get: #ofDisplayRows 0 ?DO I DrawRowData: self LOOP ;m
-
-
- \ *** optional row and column labeling routines
-
- :m DrawColNumber: { col# -- }
- gettopx: dataRect 2 + col# get: CellWidth * + ( x)
- gettopy: dataRect ascent: editField - ( y) \ 28Dec93 XXX
- MoveTo
- col# get: HScrollControl + number>$ mDrawString ;m
-
- :m DrawRowNumber: { row# -- }
- gettopx: dataRect 14 - ( x)
- gettopy: dataRect get: CellHeight + row# get: CellHeight * + ( y)
- MoveTo
- row# get: VScrollControl + number>$ mDrawString ;m
-
- :m DrawLabels:
- get: #ofDisplayRows 0
- ?DO
- I DrawRowNumber: self
- LOOP
- get: #ofDisplayColumns 0
- ?DO
- I DrawColNumber: self
- LOOP
- ;m
-
- :m new: { wptr -- }
- wptr new: EditField
- lineHeight: EditField 1+ setlineHeight: EditField \ 28Dec93 dbh
-
- init: self
-
- new: ListData
-
- noWrap: EditField
-
- gettopx: dataRect ( x) getboty: dataRect 5 + ( y)
- size: DisplayRectangle drop ( width) init: HScrollControl
- wptr new: HScrollControl
- self ( OwnerObj) scrolledBy: HScrollControl \ this must come after new:
- 0 ( lo) get: #ofColumns get: #ofDisplayColumns - ( hi) putrange: HScrollControl
-
- getbotx: dataRect 5 + ( x) gettopy: dataRect ( y)
- size: DisplayRectangle swap drop ( height) init: VScrollControl
- wptr new: VScrollControl
- self ( OwnerObj) scrolledBy: VScrollControl \ this must come after new:
- 0 ( lo) get: #ofRows get: #ofDisplayRows - ( hi) putrange: VScrollControl
-
- get: VScrollRectangle setScrollRect: VScrollControl
- get: HScrollRectangle setScrollRect: HScrollControl
-
- get: cellHeight get: #ofDisplayRows setScrollValues: VScrollControl
- get: cellWidth get: #ofDisplayColumns setScrollValues: HScrollControl
-
- get: #ofcolumns 1 <= IF hide: HScrollControl 0 -21 stretch: hitrect THEN
- get: #ofRows 1 <= IF hide: VScrollControl -21 0 stretch: hitrect THEN
-
- ;m
-
-
- :m to: ( addr len row# col# -- )
- to: listData ;m
-
-
- \ need some standard protocol select methods:
-
- :m hit?: ( -- b )
- where: theMouse
- hitRect PtinRect ;m
-
- :m focus?: ( -- t ) true ;m
-
- :m alwaysActive?: ( -- f ) false ;m
-
- :m draw:
- set: EditField \ assures that we use all of the proper font characteristics
- DrawData: self \ should draw cells before editfield
- visible?: [self]
- IF
- moveTErects: [self] \ need this because we might not have this set properly
- \ when the scrollbars send draw: messages during continuous
- \ scrolling. This was a little tricky to track down!
- draw: EditField
- THEN
- DrawGrid: self
- DrawLabels: self
- draw: VScrollControl
- draw: HScrollControl
- ;m
-
- :m release:
- release: ListData
- release: EditField
- release: VScrollControl
- release: HScrollControl ;m
-
-
-
- \ ******* the following handles cell selection and hilighting
-
- :m Visible?: ( -- b ) \ true if the current cell is visible
- get: CurrentRow ( n) get: VScrollControl ( lo)
- dup get: #ofDisplayRows + 1 - ( hi) within?
- nip \ nip n left over from within?
- get: CurrentColumn ( n) get: HScrollControl ( lo)
- dup get: #ofDisplayColumns + 1 - ( hi) within?
- nip \ nip n left over from within?
- and
- ;m \ cell is visible only if within both given ranges
-
-
- \ ******* CellLeft:, CellTop:, CellRight:, and CellBottom: return the edges of
- \ the current cell
-
- :m CellLeft: ( -- n )
- get: CurrentColumn get: HScrollControl - get: CellWidth *
- gettopx: dataRect + ;m
-
- :m CellTop: ( -- n )
- get: CurrentRow get: VScrollControl - get: CellHeight *
- gettopy: dataRect + ;m
-
- :m CellRight: ( -- n )
- CellLeft: self get: CellWidth + ;m
-
- :m CellBottom: ( -- n )
- CellTop: self get: CellHeight + ;m
-
- :m TeText->ListData: \ store the text edit characters in the data array
- get: EditField ( addr len )
- get: Characters/Cell min \ assure len is not too large!
- get: CurrentRow get: CurrentColumn to: ListData ;m
-
- :m TeText->Cell: \ display the text edit characters in the current cell
- CellLeft: self 2 + ( x) CellBottom: self descent: EditField - 1 - ( y) MoveTo \ 28Dec93 XXX
- get: EditField ( addr len )
- get: Characters/Cell min \ assure len is not too large!
- set: EditField \ 28Dec93 XXX
- mDrawString ;m
-
- :m ListData->TeText: \ place the data for the current cell into the textedit
- \ field and then select the characters in the field
- get: CurrentRow get: CurrentColumn at: ListData ( addr len)
- put: EditField
- selectall: EditField
- ;m
-
- :m ClearCell: \ erase the on-screen contents of the current cell
- CellLeft: self 1 + ( x1) CellTop: self 1 + ( y1)
- CellRight: self ( x2) CellBottom: self ( y2) put: temprect
- clear: temprect ;m
-
- :m ClearBigRectangle:
- gettopx: dataRect get: CellWidth - ( x1)
- gettopy: dataRect get: CellHeight - ( y1)
- getbotx: dataRect ( x2) getboty: dataRect ( y2) put: temprect
- clear: temprect ;m
-
- :m AdjustVertical?: ( -- b) \ true if vertical scrollbar must change
- get: CurrentRow ( n) get: VScrollControl ( lo)
- dup get: #ofDisplayRows + 1 - ( hi) within?
- nip \ nip n left over from within?
- not ;m
-
- :m AdjustHorizontal?: ( -- b) \ true if horizontal scrollbar must change
- get: CurrentColumn ( n) get: HScrollControl ( lo)
- dup get: #ofDisplayColumns + 1 - ( hi) within?
- nip \ nip n left over from within?
- not ;m
-
- :m MakeCellVisible:
- AdjustVertical?: self
- IF
- get: CurrentRow set: VScrollControl
- THEN
- AdjustHorizontal?: self
- IF
- get: CurrentColumn set: HScrollControl
- THEN
- ClearBigRectangle: self
- draw: self ;m
-
- :m MoveTErects:
- CellLeft: self 1 + ( x1) CellTop: self 1 + ( y1)
- CellRight: self ( x2) CellBottom: self ( y2) setrects: EditField ;m \ 28Dec93 XXX
-
- :m DoNewCell:
- Visible?: self not IF MakeCellVisible: self THEN
- MoveTErects: self
- ListData->TeText: self
- activate: EditField
- draw: EditField ;m
-
- :m DoCellAfterFilterTrap:
- Visible?: self not IF MakeCellVisible: self MoveTErects: self THEN
- activate: EditField
- 0 get: Characters/Cell select: EditField
- draw: EditField ;m
-
- \ note, FilterProcedure: should probably be an external action handler or object?
- :m FilterProcedure: ( -- b ) \ true if no problems with cell input data
- true ;m \ just for now
-
- :m DoOldCell: ( -- b ) \ true if no problems with cell input data
- Visible?: self
- IF deactivate: EditField ClearCell: self TeText->Cell: self THEN
- TeText->ListData: self
- FilterProcedure: self ;m
-
- :m DoNewCellAfterMouse:
- where: theMouse ( x y )
- gettopy: dataRect - get: CellHeight / get: VScrollControl + put: CurrentRow
- gettopx: dataRect - get: CellWidth / get: HScrollControl + put: CurrentColumn
- ;m
-
-
-
- \ *** more protocol methods for the scroll controls
- \ the scrolls themselves must orchestrate these actions
-
- :m prescroll:
- deactivate: EditField ;m
-
- :m postscroll:
- MoveTErects: self
- Visible?: self
- IF activate: EditField
- draw: EditField
- THEN ;m
-
- :m click:
- hit?: VScrollControl IF click: VScrollControl exit THEN
- hit?: HScrollControl IF click: HScrollControl exit THEN
-
- where: theMouse
- dataRect PtinRect NIF exit THEN
-
- hit?: EditField
- IF click: EditField
- ELSE
- \ must be in datarect, or could not have gotten here
- DoOldCell: self
- IF
- DoNewCellAfterMouse: self
- MoveTErects: self
- ListData->TeText: self
- activate: EditField
- draw: EditField
- THEN
- THEN ;m
-
- :m idle:
- visible?: self
- IF
- idle: EditField
- THEN ;m
-
- :m activate:
- activate: VScrollControl
- activate: HScrollControl
- activate: EditField
- activate: EditField
- ;m
-
- :m DoEnter:
- DoOldCell: self
- IF DoNewCell: self THEN ;m
-
- :m deactivate:
- \ must inspect any pending text from the user
- \ before allowing a deactivate
- DoEnter: self
- deactivate: VScrollControl
- deactivate: HScrollControl
- deactivate: EditField
- ;m
-
- :m DoShift-Tab:
- DoOldCell: self
- IF
- deactivate: EditField
- get: CurrentColumn 1 - 0 max put: CurrentColumn
- Visible?: self not IF -1 DoCtl: HScrollControl THEN
- DoNewCell: self
- THEN ;m
-
- :m DoTab:
- ShiftKey?: fevent
- IF
- DoShift-Tab: self
- ELSE
- DoOldCell: self
- IF
- deactivate: EditField
- get: CurrentColumn 1 + get: #ofColumns 1 - min put: CurrentColumn
- Visible?: self not IF 1 DoCtl: HScrollControl THEN
- DoNewCell: self
- THEN
- THEN ;m
-
- :m DoShift-Return:
- DoOldCell: self
- IF
- deactivate: EditField
- get: CurrentRow 1 - 0 max put: CurrentRow
- Visible?: self not IF -1 DoCtl: VScrollControl THEN
- DoNewCell: self
- THEN ;m
-
- :m DoReturn:
- ShiftKey?: fevent
- IF
- DoShift-Return: self
- ELSE
- DoOldCell: self
- IF
- deactivate: EditField
- get: CurrentRow 1 + get: #ofRows 1 - min put: CurrentRow
- Visible?: self not IF 1 DoCtl: VScrollControl THEN
- DoNewCell: self
- THEN
- THEN ;m
-
- :m AssureTEvisible:
- Visible?: self not
- IF
- deactivate: EditField
- MakeCellVisible: self
- MoveTERects: self
- activate: EditField
- draw: EditField
- THEN ;m
-
- :m key: ( char -- )
- CASE
- 3 OF DoEnter: self ENDOF
- 9 OF DoTab: self ENDOF
- 13 OF DoReturn: self ENDOF
- 28 OF DoShift-Tab: self ENDOF \ left-arrow
- 29 OF DoTab: self ENDOF \ right-arrow
- 30 OF DoShift-Return: self ENDOF \ up-arrow
- 31 OF DoReturn: self ENDOF \ down-arrow
- ( all other keys)
- AssureTEvisible: self
- key: EditField
- 0 ( 0 is dropped by endcase)
- ENDCASE
- EditField call ValidRect
- ;m
-
- :m cut:
- AssureTEvisible: self
- cut: EditField ;m
-
- :m copy:
- AssureTEvisible: self
- copy: EditField ;m
-
- :m paste:
- AssureTEvisible: self
- paste: EditField ;m
-
- :m clear:
- AssureTEvisible: self
- clear: EditField ;m
-
- ;class
-
- endload
-
- *** EXAMPLE USE
-
- selwindow w
- test: w
-
- editlist e
- e add: w
-